


package gregorytersoff_boundary;

import gregorytersoff_controller.ChoiceController;
import gregorytersoff_controller.Easierpassing;
import gregorytersoff_controller.Easierpassing2;
import gregorytersoff_controller.ErrorController;
import gregorytersoff_model.Model;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JLabel;



import java.awt.Insets;



/**DecisionlinesGUI sets up the GUI for Decisionlines. Generates all the graphics except for the drawlines used to generate the lines for each choice and the
 * edges. This class generates the JTextFields for the user to write choices into, creates labels that are changed to give feedback to the user outside
 * of the console, and generates the visible button for adding edges, and the invisible buttons used to add an edge or to inform the user they're
 * clicking in the wrong place.
 * 
 */


public class DecisionlinesGUI extends JFrame {

	private JPanel contentPane;
	private JTextField[] choicetext;
	private Graphics g;
	private Model model;
	private LineCanvas linecanvas;
	private JButton[][] linegrid;
	private JLabel errorLabel;
	private JLabel roundLabel;
	




	/**DecisionlinesGUI generates all aspects of the GUI except for the lines drawn for each choice and edge. The potential edges are represented
	 * by a list of JButtons (since each line needs to be separated by 7 pixels, having set potential lines 7 pixels apart made the required
	 * minimum height of the lines, and by extension the window, should there be 8 options and rounds, about half that if each line could be
	 * added at any height bounded by the lines [7 pixels for the height of each button*64 potential unique heights to be represented by a 
	 * button vs 12+1 potential separation between lines * 64 different heights required (with the area above the top line and below the bottom
	 * both being 6, meaning this is not a fencepost problem], and using JButtons at that point seemed more efficient than detecting the
	 * coordinates of a mouse click), the choices are chosen by inputting to a JTextField, and error messages and the number of rounds are
	 * indicated by JLabels which can be reset. 
	 * 
	 * @param model The model for decisionlines, which contains the number of rounds and the number of options
	 */
	public DecisionlinesGUI(Model m) {
		model = m;
		choicetext = new JTextField[model.getNumoptions()];
		linegrid = new JButton[model.getNumoptions()-1][64];
		setTitle("Decision Lines");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, model.getWidth(), model.getHeight());
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		for(int j = 0; j < model.getNumoptions(); j++)
		{
			choicetext[j] = new JTextField();
			choicetext[j].addActionListener(new Easierpassing2(j, this, model) );
			choicetext[j].setBounds(model.getSpacing() * (17 - (2 * model.getNumoptions() - 1) + 4*j), 30, model.getSpacing()*2, 20);
			contentPane.add(choicetext[j]);
			choicetext[j].setColumns(1);
		}
		
		for (int a = 0; a<64; a++)
		{
			for (int b = 0; b<model.getNumoptions()-1; b++)
			{
				linegrid[b][a] = new JButton("");
				linegrid[b][a].addActionListener(new Easierpassing(b, a, this, model) );
				linegrid[b][a].setMargin(new Insets(0, 0, 0, 0));
				linegrid[b][a].setContentAreaFilled(false);
				linegrid[b][a].setOpaque(false);
				linegrid[b][a].setBorder(null);
				linegrid[b][a].setBounds(model.getSpacing() * (17 - (2 * model.getNumoptions()-2) + 4*b), 55+7*a, model.getSpacing()*4, 7);
				contentPane.add(linegrid[b][a]);
			}
		}
		
		
		
		
		JButton badZone1 = new JButton("");
		badZone1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				new ErrorController("Edges can only be added between the lines", DecisionlinesGUI.this).process();
			}
		});
		badZone1.setMargin(new Insets(0, 0, 0, 0));
		badZone1.setContentAreaFilled(false);
		badZone1.setOpaque(false);
		badZone1.setBorder(null);
		badZone1.setBounds(0, 50, model.getSpacing() * (17 - (2 * model.getNumoptions() - 1)+1), model.getHeight() - 200);
		contentPane.add(badZone1);
		
		JButton badZone2 = new JButton("");
		badZone2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				new ErrorController("Edges can only be added between the lines", DecisionlinesGUI.this).process();
			}
		});
		badZone2.setMargin(new Insets(0, 0, 0, 0));
		badZone2.setContentAreaFilled(false);
		badZone2.setOpaque(false);
		badZone2.setBorder(null);
		badZone2.setBounds( model.getSpacing() * (17 - (2 * model.getNumoptions() - 1)), model.getHeight() - 200, model.getSpacing() * 4*model.getNumoptions(), 50);
		contentPane.add(badZone2);
		
		
		
		
		
		JButton badZone3 = new JButton("");
		badZone3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				new ErrorController("Edges can only be added between the lines", DecisionlinesGUI.this).process();
			}
		});
		badZone3.setMargin(new Insets(0, 0, 0, 0));
		badZone3.setContentAreaFilled(false);
		badZone3.setOpaque(false);
		badZone3.setBorder(null);
		badZone3.setBounds(model.getSpacing() * 4*model.getNumoptions(), 50, model.getWidth()-200 - (model.getSpacing() * 4*model.getNumoptions()), model.getHeight() - 200);
		contentPane.add(badZone3);
		
		
		
		roundLabel = new JLabel("Round "+model.getCurrentRound() + "/" + model.getRounds());
		roundLabel.setBounds(model.getWidth()-200, 200, 150, 23);
		contentPane.add(roundLabel);
		
		errorLabel = new JLabel("Any errors will appear here");
		errorLabel.setBounds(200, model.getHeight()-150, 1000, 23);
		contentPane.add(errorLabel);
		
		JButton btnSetChoices = new JButton("Set Choices");
		btnSetChoices.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				new ChoiceController(DecisionlinesGUI.this, model).process();	
			}
		});
		btnSetChoices.setBounds(model.getWidth()-200, 30, 150, 23);
		contentPane.add(btnSetChoices);
		
		linecanvas = new LineCanvas(model);
		linecanvas.setSize(model.getWidth(), model.getHeight());
		contentPane.add(linecanvas);
		
		
		
	}
	
	/**lockChoices prevents further editing of the choices once the user signals that they are ready to add edges, and is only called once each
	 * choice is a valid and unique string. This method is a holdover from when the program would check the validity of the choices all at once,
	 * rather than one at a time.
	 * 
	 * @return The list of names for the choices, to avoid having the controller which calls this method through the DecisionlinesGUI then have
	 * to go through each text field to get the names of the choices
	 */
	public String[] lockChoices()
	{
		String[] results = new String[choicetext.length];		
		for(int i = 0; i<choicetext.length; i++)
		{
			results[i] = choicetext[i].getText();
			choicetext[i].setEditable(false);
		}
		return results;
	}
	
	/**checkFilled establishes that each choice has a non-empty string. This method is a holdover from when the program would check the validity 
	 * of the choices all at once, rather than one at a time.
	 * 
	 * @return a boolean indicating whether or not every text field has a string of length greater than zero
	 */
	public boolean checkFilled()
	{
		for(int j = 0; j<choicetext.length; j++)
		{
			if( "".equals(choicetext[j].getText()) )
			{
				return false;
			}
		}
		return true;
	}
	
	/**Used to access the LineCanvas used to draw lines, primarily so that more edges can be added to it
	 * 
	 * @return the LineCanvas used to draw lines for this particular DecisionlinesGUI
	 */
	public LineCanvas getLineCanvas()
	{
		return linecanvas;
	}
	
	/**Changes the error message, either to whatever error occured (such as the user clicking near but outside the lines) or back to the
	 * default string letting the user know what the label is for
	 * 
	 * @param text The string to be displayed on the JLabel at the bottom of the window
	 */
	public void resetErrorText(String text)
	{
		errorLabel.setText(text);
	}
	/**
	 * Updates the label indicating what round is currently happening
	 */
	public void resetRounds()
	{
		roundLabel.setText("Round "+model.getCurrentRound() + "/" + model.getRounds());
	}
	/**Allows access to the JTextFields used for naming choices
	 * 
	 * @return The list of JTextFields used to name the choices
	 */
	public JTextField[] getChoiceText()
	{
		return choicetext;
	}
	/**Locks an individual text field, used once a choice has been established as unique
	 * 
	 * @param i integer indicating which JTextField should be locked
	 */
	public void setLocked(int i)
	{
		choicetext[i].setEditable(false);
	}
	
}
